#include <stdio.h>
#include "hi_ext_util.h"
#include "plug_datamng.h"
#include "cJSON.h"

#ifdef __cplusplus
#if __cplusplus
extern "C" {
#endif
#endif /* End of #ifdef __cplusplus */

/*Read the file to the memory, the returned pointer needs to be released manually*/
HI_CHAR* DATAMNG_FileToBuff(HI_CHAR *pazFileName, HI_S32* s32OutLen)
{
    HI_APPCOMM_CHECK_POINTER(pazFileName, HI_NULL);
    HI_APPCOMM_CHECK_POINTER(s32OutLen, HI_NULL);

    FILE *fp = fopen(pazFileName, "rb");
    if (!fp) {
        printf("can't read %s\n", pazFileName);
        return HI_NULL;
    }
    
    fseek(fp,0,SEEK_END);
    *s32OutLen = ftell(fp);
    
    HI_CHAR *azBuff = (HI_CHAR*)calloc(*s32OutLen+1, 1);
	if (HI_NULL == azBuff) {
		LOGE("malloc for s32OutLen failed, size(%d)\n", *s32OutLen);
		fclose(fp);
		return HI_NULL;
	}
    fseek(fp,0,0);
    fread(azBuff, *s32OutLen, 1, fp);
    fclose(fp);
    
    return azBuff;
}

HI_S32 PLUG_DATAMNG_WriteConfig(HI_CHAR *pazFileName, PLUG_COMMON_DEV_INFO_S stInfo)
{
    HI_APPCOMM_CHECK_POINTER(pazFileName, HI_NULL);
    
    HI_S32 s32Ret = HI_SUCCESS;
    HI_CHAR *pszString = HI_NULL;
    FILE *pFp = HI_NULL;
    cJSON *pJsonRoot = HI_NULL;
    cJSON *pJsonInfo = HI_NULL;
    
    pJsonRoot = cJSON_CreateObject();
    if (HI_NULL == pJsonRoot)
    {
        LOGE("cJSON_CreateObject fail!\n");
        return HI_FAILURE;
    }
    

    cJSON_AddItemToObject(pJsonRoot, "devinfo", pJsonInfo = cJSON_CreateObject());
    
    if (HI_NULL != pJsonInfo)
    {
        cJSON_AddStringToObject(pJsonInfo, "device_info", stInfo.azDeviceId);
        cJSON_AddStringToObject(pJsonInfo, "mqtt_address", stInfo.azMqttAddress);

        cJSON_AddStringToObject(pJsonInfo, "user_id", stInfo.azUserId);
        cJSON_AddStringToObject(pJsonInfo, "user_pwd", stInfo.azPassword);
        cJSON_AddStringToObject(pJsonInfo, "stream_ip", stInfo.azStreamIp);

        cJSON_AddNumberToObject(pJsonInfo, "stream_port", stInfo.s32StreamPort);

        cJSON_AddNumberToObject(pJsonInfo, "temp_thres", stInfo.s32TempThres);
        cJSON_AddNumberToObject(pJsonInfo, "hum_thres", stInfo.s32HumThres);
        cJSON_AddNumberToObject(pJsonInfo, "smoke_thres", stInfo.s32SmokeThres);

        cJSON_AddNumberToObject(pJsonInfo, "distance_aHead_warn", stInfo.s32DisAheadWarn);
        cJSON_AddNumberToObject(pJsonInfo, "distance_Below_warn_hight", stInfo.s32DisBlowWarnHight);
        cJSON_AddNumberToObject(pJsonInfo, "distance_Below_warn_low", stInfo.s32DisBlowWarnLow);
    }
    
    pszString = cJSON_Print(pJsonRoot);
    pFp = fopen(pazFileName, "w");
    if (HI_NULL == pFp)
    {
        LOGE("fopen %s failed!\n", pazFileName);
        goto ERROR;
    }
    
    fwrite(pszString, sizeof(HI_CHAR), strlen(pszString), pFp);
    if (HI_NULL != pFp)
    {
        fclose(pFp);
        pFp = HI_NULL;
    }
    
    if (pJsonRoot)
    {
        cJSON_Delete(pJsonRoot);
    }

    if(pszString)
    {
        free(pszString);
        pszString = HI_NULL;
    }
    
    LOGI("Write Succ.\n");
    
    return HI_SUCCESS;

ERROR:
    if (HI_NULL != pFp)
    {
        fclose(pFp);
        pFp = HI_NULL;
    }
    if (pJsonRoot)
    {
        cJSON_Delete(pJsonRoot);
    }
    
    if(pszString)
    {
        free(pszString);
        pszString = HI_NULL;
    }
    
    remove(pazFileName);
    return HI_FAILURE;
}

HI_S32 PLUG_DATAMNG_ReadConfig(HI_CHAR *pazFileName, PLUG_COMMON_DEV_INFO_S* pstInfo)
{
    HI_APPCOMM_CHECK_POINTER(pazFileName, HI_NULL);
    HI_APPCOMM_CHECK_POINTER(pstInfo, HI_NULL);
    
    HI_S32 s32Ret = HI_SUCCESS;
    HI_S32 s32OutLen = 0;
    HI_CHAR *azFileBuff = HI_NULL;
    cJSON *pJsonRoot = HI_NULL;
    cJSON *pObjItem = HI_NULL;
    cJSON *pSubObjItem = HI_NULL;
    
    azFileBuff = DATAMNG_FileToBuff(pazFileName, &s32OutLen);
    if (HI_NULL == azFileBuff) 
    {
        LOGE("read[%s] error\n", pazFileName);
        return HI_FAILURE;
    }

    pJsonRoot = cJSON_Parse(azFileBuff);
    if (HI_NULL == pJsonRoot) 
    {
        LOGE("cJSON_Parse for JsonRoot failed\n");
        if (azFileBuff)
        {
            free(azFileBuff);
        }
        
        remove(pazFileName);
        
        return HI_FAILURE;
    }
    
    /*Get members of this object*/
    pObjItem = cJSON_GetObjectItem(pJsonRoot,"devinfo");
    if ((HI_NULL == pObjItem) || (cJSON_Object != pObjItem->type))
    {
        LOGE("cJSON_GetObjectItem pObjItem fail!\n");
        return HI_FAILURE;
    }
    
    pSubObjItem = cJSON_GetObjectItem(pObjItem, "device_info");
    if ((HI_NULL != pSubObjItem) && (cJSON_String == pSubObjItem->type) && (HI_NULL != pSubObjItem->valuestring))
    {
        memset(pstInfo->azDeviceId, 0x0, sizeof(pstInfo->azDeviceId));
        snprintf(pstInfo->azDeviceId, sizeof(pstInfo->azDeviceId), "%s", pSubObjItem->valuestring);
    }
    
    pSubObjItem = cJSON_GetObjectItem(pObjItem, "mqtt_address");
    if ((HI_NULL != pSubObjItem) && (cJSON_String == pSubObjItem->type) && (HI_NULL != pSubObjItem->valuestring))
    {
        memset(pstInfo->azMqttAddress, 0x0, sizeof(pstInfo->azMqttAddress));
        snprintf(pstInfo->azMqttAddress, sizeof(pstInfo->azMqttAddress), "%s", pSubObjItem->valuestring);
    }
    
    pSubObjItem = cJSON_GetObjectItem(pObjItem, "user_id");
    if ((HI_NULL != pSubObjItem) && (cJSON_String == pSubObjItem->type) && (HI_NULL != pSubObjItem->valuestring))
    {
        memset(pstInfo->azUserId, 0x0, sizeof(pstInfo->azUserId));
        snprintf(pstInfo->azUserId, sizeof(pstInfo->azUserId), "%s", pSubObjItem->valuestring);
    }

    pSubObjItem = cJSON_GetObjectItem(pObjItem, "user_pwd");
    if ((HI_NULL != pSubObjItem) && (cJSON_String == pSubObjItem->type) && (HI_NULL != pSubObjItem->valuestring))
    {
        memset(pstInfo->azPassword, 0x0, sizeof(pstInfo->azPassword));
        snprintf(pstInfo->azPassword, sizeof(pstInfo->azPassword), "%s", pSubObjItem->valuestring);
    }

    pSubObjItem = cJSON_GetObjectItem(pObjItem, "stream_ip");
    if ((HI_NULL != pSubObjItem) && (cJSON_String == pSubObjItem->type) && (HI_NULL != pSubObjItem->valuestring))
    {
        memset(pstInfo->azStreamIp, 0x0, sizeof(pstInfo->azStreamIp));
        snprintf(pstInfo->azStreamIp, sizeof(pstInfo->azStreamIp), "%s", pSubObjItem->valuestring);
    }

    pSubObjItem = cJSON_GetObjectItem(pObjItem, "stream_port");
    if ((HI_NULL != pSubObjItem) && (cJSON_Number == pSubObjItem->type))
    {
        pstInfo->s32StreamPort = pSubObjItem->valueint;
    }
    pSubObjItem = cJSON_GetObjectItem(pObjItem, "temp_thres");
    if ((HI_NULL != pSubObjItem) && (cJSON_Number == pSubObjItem->type))
    {
        pstInfo->s32TempThres = pSubObjItem->valueint;
    }
    
    pSubObjItem = cJSON_GetObjectItem(pObjItem, "hum_thres");
    if ((HI_NULL != pSubObjItem) && (cJSON_Number == pSubObjItem->type))
    {
        pstInfo->s32HumThres = pSubObjItem->valueint;
    }
    
    pSubObjItem = cJSON_GetObjectItem(pObjItem, "smoke_thres");
    if ((HI_NULL != pSubObjItem) && (cJSON_Number == pSubObjItem->type))
    {
        pstInfo->s32SmokeThres = pSubObjItem->valueint;
    }
    
    pSubObjItem = cJSON_GetObjectItem(pObjItem, "distance_aHead_warn");
    if ((HI_NULL != pSubObjItem) && (cJSON_Number == pSubObjItem->type))
    {
        pstInfo->s32DisAheadWarn = pSubObjItem->valueint;
    }
    
    pSubObjItem = cJSON_GetObjectItem(pObjItem, "distance_Below_warn_hight");
    if ((HI_NULL != pSubObjItem) && (cJSON_Number == pSubObjItem->type))
    {
        pstInfo->s32DisBlowWarnHight = pSubObjItem->valueint;
    }
    
    pSubObjItem = cJSON_GetObjectItem(pObjItem, "distance_Below_warn_low");
    if ((HI_NULL != pSubObjItem) && (cJSON_Number == pSubObjItem->type))
    {
        pstInfo->s32DisBlowWarnLow = pSubObjItem->valueint;
    }

    if (pJsonRoot)
    {
        cJSON_Delete(pJsonRoot);
    }
    
    if (azFileBuff)
    {
        free(azFileBuff);
    }
    
    LOGI("Update Dev Succ.\n");
    
    return HI_SUCCESS;
}

#ifdef __cplusplus
#if __cplusplus
}
#endif
#endif /* End of #ifdef __cplusplus */

